import json
import logging
import threading
import time
import traceback
from concurrent.futures._base import Future
from concurrent.futures.thread import ThreadPoolExecutor
from dataclasses import dataclass
import coloredlogs
import openai
from django_redis import get_redis_connection
from redis.client import Redis
from rest_framework.generics import get_object_or_404

from .models import DemoTable
from .serializers import DemoUSerializer
from .settings import chatgpt_settings
logger = logging.getLogger(__name__)

@dataclass
class OpenAI:
    def run(self, input):
        """
        model: https://beta.openai.com/docs/models/gpt-3
        :param input:
        :return:
        """
        logger.debug(f"chatgpt apikey {chatgpt_settings.API_KEY}")
        openai.api_key = chatgpt_settings.API_KEY
        res = openai.Completion.create(
            model="text-davinci-003",
            prompt=input,
            temperature=chatgpt_settings.TEMPERATURE,
            max_tokens=chatgpt_settings.MAX_TOKENS,
            stop=None
        )
        return res.choices[0].text


@dataclass
class Daemon:
    def work(self, item: dict):
        obj = get_object_or_404(queryset=DemoTable.objects.all(), uuid=item['uuid'])
        try:
            openapi = OpenAI()
            text = openapi.run(item['req'])
            logger.warning(f"\n{item['req']}\n========================\n{text}\n\n")

            serializer = DemoUSerializer(instance=obj,data=item | {'ans': text, 'state': DemoTable.State.FINISHED })
            serializer.is_valid(raise_exception=True)
            logger.debug(serializer.validated_data)
            serializer.save()

        except:
            serializer = DemoUSerializer(instance=obj,data=item | {'ans': (eror:=str(traceback.format_exc())), 'state': DemoTable.State.ERROR })
            serializer.is_valid(raise_exception=True)
            logger.debug(serializer.validated_data)
            serializer.save()
            logger.error(f"发现异常 {eror}")

    def _threadpool(self):
        pool = ThreadPoolExecutor(max_workers=chatgpt_settings.THREADS)
        daemons: list[Future] = []

        while True:
            try:
                redis_cli: Redis = get_redis_connection('default')
                item = redis_cli.rpop('msg')
                logger.debug(f"获取到消息{item}")
                if not item:
                    time.sleep(2)
                    logger.debug('没有消息休息2s')
                    continue
                item = json.loads(item.decode())
                logger.warning(f'拿到消息: --> {item}')

                daemons.append(pool.submit(self.work, item))  # 线程中启动多个线程
            except Exception as e:
                logger.error(f"发现错误: {e}")

            time.sleep(2)


    def run(self):
        self._threadpool()



